package com.bifrost.entity;

import com.bifrost.constant.CustomerSource;
import org.hibernate.annotations.DynamicUpdate;

import java.io.Serializable;
import javax.persistence.*;
import java.util.Date;
import java.math.BigInteger;
import java.util.List;


/**
 * The persistent class for the CUSTOMER database table.
 */
@Entity
@Table(name = "CUSTOMER",indexes = {
        @Index(name = "OPEN_ID_INDEX",columnList = "OPEN_ID",unique = true),
        @Index(name = "UNION_ID_INDEX",columnList = "UNION_ID",unique = false),
        @Index(name = "LOYALTY_CARD_INDEX",columnList = "LOYALTY_CARD",unique = false),
        @Index(name = "MERCHANT_LOYALTY_CARD_INDEX",columnList = "MERCHANT_ID,LOYALTY_CARD",unique = true)
})
@NamedQuery(name = "Customer.findAll", query = "SELECT c FROM Customer c")
@DynamicUpdate
public class Customer extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;

    public static final String LOCK_KEY_PERFIX="com.bifrost.customer";

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "CUSTOMER_ID", unique = true, nullable = false)
    private Long customerId;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "AUTHTOKEN_EXPIRY")
    private Date authtokenExpiry;

    @Column(name = "BONUS_POINTS" , updatable = false)
    private BigInteger bonusPoints=BigInteger.ZERO;

    @Column(name = "CUSTOMER_AUTHTOKEN", length = 255)
    private String customerAuthtoken;

    @Column(name = "CUSTOMER_BIRTHDAY", length = 20)
    private String customerBirthday;

    @Column(name = "CUSTOMER_EMAIL", length = 100)
    private String customerEmail;

    @Column(name = "CUSTOMER_GENDER", length = 1)
    private String customerGender;

    @Column(name = "CUSTOMER_LASTNAME", nullable = false, length = 128)
    private String customerLastname;

    @Column(name = "CUSTOMER_NICKNAME", length = 100)
    private String customerNickname;

    @Column(name = "CUSTOMER_PASSWORD", nullable = false, length = 64)
    private String customerPassword;

    @Column(name = "CUSTOMER_PHONE", length =16)
    private String customerPhone;

    @Column(name = "CUSTOMER_PUBLICKEY", length = 255)
    private String customerPublickey;

    @Column(name = "CUSTOMER_SALUTATION", length = 32)
    private String customerSalutation;

    @Column(name = "IDENTIFICATION_ID", length = 50)
    private String identificationId;

    @Column(name = "IS_ACTIVE")
    private Boolean isActive;

    @Column(name = "LAST_LOGIN_DATE")
    @Temporal(TemporalType.TIMESTAMP)
    private Date lastLoginDate;

    @Column(name = "OPEN_ID", length = 32)
    private String openId;
    @Column(name = "UNION_ID", length = 32)
    private String unionId;
    @Column(name = "LOYALTY_CARD", length =32)
    private String loyaltyCard;
    @Column(name = "SOURCE",length = 32)
    private String source = CustomerSource.MP_SUBSCRIBE;

    @Column(name = "IS_SYNC")//是否已同步到中间库
    private Boolean sync = Boolean.FALSE;

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name="MERCHANT_ID", nullable=true,foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
    private MerchantStore merchantStore;


    //bi-directional many-to-one association to CouponDetail
    @OneToMany(mappedBy = "customer", fetch = FetchType.LAZY)
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<CouponDetail> couponDetails;

    //bi-directional many-to-one association to CustomerType
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CUSTOMER_TYPE",foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
    private CustomerType customerType;

    //bi-directional many-to-one association to Media
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "CUSTOMER_AVATAR",foreignKey = @ForeignKey(name = "none", value = ConstraintMode.NO_CONSTRAINT))
    private Media media;

    //bi-directional many-to-one association to CustomerAddress
    @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<CustomerAddress> customerAddresses;

    //bi-directional many-to-one association to CustomerAttribute
    @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<CustomerAttribute> customerAttributes;

    //bi-directional many-to-one association to CustomerWishlist
    @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<CustomerWishlist> customerWishlists;

    //bi-directional many-to-one association to Order
    @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<Order> orders;

    @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<OrderReturn> orderReturns;

    //bi-directional many-to-one association to ShoppingCart
    @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<ShoppingCart> shoppingCarts;

    @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<DailySignInHistory> dailyHistories;

   /* @OneToMany(mappedBy = "customer")
    @org.hibernate.annotations.ForeignKey(name = "none")
    private List<BonusPointsHistory> bonusPointsHistories;*/

    public Customer() {
    }

    public Long getCustomerId() {
        return this.customerId;
    }

    public void setCustomerId(Long customerId) {
        this.customerId = customerId;
    }

    public Date getAuthtokenExpiry() {
        return this.authtokenExpiry;
    }

    public void setAuthtokenExpiry(Date authtokenExpiry) {
        this.authtokenExpiry = authtokenExpiry;
    }

    public BigInteger getBonusPoints() {
        return this.bonusPoints;
    }

    public void setBonusPoints(BigInteger bonusPoints) {
        this.bonusPoints = bonusPoints;
    }


    public String getCustomerAuthtoken() {
        return this.customerAuthtoken;
    }

    public void setCustomerAuthtoken(String customerAuthtoken) {
        this.customerAuthtoken = customerAuthtoken;
    }

    public String getCustomerBirthday() {
        return this.customerBirthday;
    }

    public void setCustomerBirthday(String customerBirthday) {
        this.customerBirthday = customerBirthday;
    }

    public String getCustomerEmail() {
        return this.customerEmail;
    }

    public void setCustomerEmail(String customerEmail) {
        this.customerEmail = customerEmail;
    }

    public String getCustomerGender() {
        return this.customerGender;
    }

    public void setCustomerGender(String customerGender) {
        this.customerGender = customerGender;
    }

    public String getCustomerLastname() {
        return this.customerLastname;
    }

    public void setCustomerLastname(String customerLastname) {
        this.customerLastname = customerLastname;
    }

    public String getCustomerNickname() {
        return this.customerNickname;
    }

    public void setCustomerNickname(String customerNickname) {
        this.customerNickname = customerNickname;
    }

    public String getCustomerPassword() {
        return this.customerPassword;
    }

    public void setCustomerPassword(String customerPassword) {
        this.customerPassword = customerPassword;
    }

    public String getCustomerPhone() {
        return this.customerPhone;
    }

    public void setCustomerPhone(String customerPhone) {
        this.customerPhone = customerPhone;
    }

    public String getCustomerPublickey() {
        return this.customerPublickey;
    }

    public void setCustomerPublickey(String customerPublickey) {
        this.customerPublickey = customerPublickey;
    }

    public String getCustomerSalutation() {
        return this.customerSalutation;
    }

    public void setCustomerSalutation(String customerSalutation) {
        this.customerSalutation = customerSalutation;
    }

    public String getIdentificationId() {
        return this.identificationId;
    }

    public void setIdentificationId(String identificationId) {
        this.identificationId = identificationId;
    }

    public Boolean isActive() {
        return this.isActive;
    }

    public void setActive(Boolean isActive) {
        this.isActive = isActive;
    }

    public String getOpenId() {
        return this.openId;
    }

    public void setOpenId(String openId) {
        this.openId = openId;
    }

    public String getUnionId() {
        return unionId;
    }

    public void setUnionId(String unionId) {
        this.unionId = unionId;
    }

    public String getLoyaltyCard() {
        return loyaltyCard;
    }

    public void setLoyaltyCard(String loyaltyCard) {
        this.loyaltyCard = loyaltyCard;
    }

    public String getSource() {
        return source;
    }

    public void setSource(String source) {
        this.source = source;
    }

    public List<CouponDetail> getCouponDetails() {
        return this.couponDetails;
    }

    public void setCouponDetails(List<CouponDetail> couponDetails) {
        this.couponDetails = couponDetails;
    }

    public CouponDetail addCouponDetail(CouponDetail couponDetail) {
        getCouponDetails().add(couponDetail);
        couponDetail.setCustomer(this);

        return couponDetail;
    }

    public CouponDetail removeCouponDetail(CouponDetail couponDetail) {
        getCouponDetails().remove(couponDetail);
        couponDetail.setCustomer(null);

        return couponDetail;
    }

    public CustomerType getCustomerType() {
        return customerType;
    }

    public void setCustomerType(CustomerType customerType) {
        this.customerType = customerType;
    }

    public Media getMedia() {
        return this.media;
    }

    public void setMedia(Media media) {
        this.media = media;
    }

    public List<CustomerAddress> getCustomerAddresses() {
        return this.customerAddresses;
    }

    public void setCustomerAddresses(List<CustomerAddress> customerAddresses) {
        this.customerAddresses = customerAddresses;
    }

    public CustomerAddress addCustomerAddress(CustomerAddress customerAddress) {
        getCustomerAddresses().add(customerAddress);
        customerAddress.setCustomer(this);

        return customerAddress;
    }

    public CustomerAddress removeCustomerAddress(CustomerAddress customerAddress) {
        getCustomerAddresses().remove(customerAddress);
        customerAddress.setCustomer(null);

        return customerAddress;
    }

    public List<CustomerAttribute> getCustomerAttributes() {
        return this.customerAttributes;
    }

    public void setCustomerAttributes(List<CustomerAttribute> customerAttributes) {
        this.customerAttributes = customerAttributes;
    }

    public CustomerAttribute addCustomerAttribute(CustomerAttribute customerAttribute) {
        getCustomerAttributes().add(customerAttribute);
        customerAttribute.setCustomer(this);

        return customerAttribute;
    }

    public CustomerAttribute removeCustomerAttribute(CustomerAttribute customerAttribute) {
        getCustomerAttributes().remove(customerAttribute);
        customerAttribute.setCustomer(null);

        return customerAttribute;
    }

    public List<CustomerWishlist> getCustomerWishlists() {
        return this.customerWishlists;
    }

    public void setCustomerWishlists(List<CustomerWishlist> customerWishlists) {
        this.customerWishlists = customerWishlists;
    }

    public CustomerWishlist addCustomerWishlist(CustomerWishlist customerWishlist) {
        getCustomerWishlists().add(customerWishlist);
        customerWishlist.setCustomer(this);

        return customerWishlist;
    }

    public CustomerWishlist removeCustomerWishlist(CustomerWishlist customerWishlist) {
        getCustomerWishlists().remove(customerWishlist);
        customerWishlist.setCustomer(null);

        return customerWishlist;
    }

    public List<Order> getOrders() {
        return this.orders;
    }

    public void setOrders(List<Order> orders) {
        this.orders = orders;
    }

    public Order addOrder(Order order) {
        getOrders().add(order);
        order.setCustomer(this);

        return order;
    }

    public Order removeOrder(Order order) {
        getOrders().remove(order);
        order.setCustomer(null);

        return order;
    }

    public List<ShoppingCart> getShoppingCarts() {
        return this.shoppingCarts;
    }

    public void setShoppingCarts(List<ShoppingCart> shoppingCarts) {
        this.shoppingCarts = shoppingCarts;
    }

    public ShoppingCart addShoppingCart(ShoppingCart shoppingCart) {
        getShoppingCarts().add(shoppingCart);
        shoppingCart.setCustomer(this);

        return shoppingCart;
    }

    public ShoppingCart removeShoppingCart(ShoppingCart shoppingCart) {
        getShoppingCarts().remove(shoppingCart);
        shoppingCart.setCustomer(null);

        return shoppingCart;
    }

  /*  public List<BonusPointsHistory> getBonusPointsHistories() {
        return bonusPointsHistories;
    }

    public void setBonusPointsHistories(List<BonusPointsHistory> bonusPointsHistories) {
        this.bonusPointsHistories = bonusPointsHistories;
    }

    public BonusPointsHistory addBonusPointsHistory(BonusPointsHistory history) {
        getBonusPointsHistories().add(history);
        history.setCustomer(this);
        return history;
    }

    public BonusPointsHistory removeBonusPointsHistory(BonusPointsHistory history) {
        getBonusPointsHistories().remove(history);
        history.setCustomer(null);
        return history;
    }*/

    public MerchantStore getMerchantStore() {
        return merchantStore;
    }

    public void setMerchantStore(MerchantStore merchantStore) {
        this.merchantStore = merchantStore;
    }

    public List<OrderReturn> getOrderReturns() {
        return orderReturns;
    }

    public void setOrderReturns(List<OrderReturn> orderReturns) {
        this.orderReturns = orderReturns;
    }

    public Date getLastLoginDate() {
        return lastLoginDate;
    }

    public void setLastLoginDate(Date lastLoginDate) {
        this.lastLoginDate = lastLoginDate;
    }

    public Boolean getSync() {
        return sync;
    }

    public void setSync(Boolean sync) {
        this.sync = sync;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        Customer customer = (Customer) o;

        if (!getCustomerId().equals(customer.getCustomerId())) {
            return false;
        }
        if (!getCustomerPassword().equals(customer.getCustomerPassword())) {
            return false;
        }
        if (!getCustomerPhone().equals(customer.getCustomerPhone())) {
            return false;
        }
        return true;
    }


    @Override
    public int hashCode() {
        int result = getCustomerId().hashCode();
        result = 31 * result + getCustomerPassword().hashCode();
        result = 31 * result + getCustomerPhone().hashCode();
        return result;
    }
}